//
//  ParserToRIG.java
//  TopoManipApplet
//
//  Created by Thibaud PIQUET on 09/04/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

package src.convertisseur;
import java.util.*;
import java.io.*;
import org.jdom.*;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
import org.xml.sax.SAXException;
import java.net.*;

/**
 *
 * @author Thibaud PIQUET
 */
public class ParserToRIG implements Runnable{
	
    File ftp; // File to parse
	File fileOut; // File to create
    Writer fw; // File Writer
    BufferedWriter bw; // Buffer Writer
    String line;
    String chaine;
    String[] res;
	
    public ParserToRIG(File file, File fileOUT) throws IOException {
        this.ftp = file;
		this.fileOut = fileOUT;
        this.fw = new FileWriter(this.fileOut);
        this.bw = new BufferedWriter(this.fw);
    }
	
	public void run() {
		try {
			this.parseToRIG();
		}
		catch (Exception e) {
			e.printStackTrace();
			Resume result = Resume.getInstance();
			result.add("ParserToRIG","procedure run had some problems : "+e);
		}
	}

	public void parseToRIG() throws IOException {
		
		Element domain;
		Element topology;
		Element nodes;
		Element links;
		
		Resume result = Resume.getInstance();

		try {
			
            // **********************************************************
            // Default values for RIG if there aren't in the XML file
            // -- Node
            // AS : 1   
            // latitude : 1.0
            // longitude : 1.0
            // ----------------
            // -- Edge
            // srcAS : 1
            // tgtAS : 1
            // length : undef
            // bandwidth : 1Mb
            // delay : undef
            // weight : 100
            // linkType : I (for internal)
            // **********************************************************
			
			/************************************************************ Loading default values *************************************************************/
			InputStream inDefaultValues = getClass().getResourceAsStream("/resources/configuration.xml");
			
			org.jdom.input.SAXBuilder builderConfig = new org.jdom.input.SAXBuilder();
            builderConfig.setIgnoringElementContentWhitespace(true);
            org.jdom.Document documentDefaultValues = builderConfig.build(inDefaultValues);
			
			Element defaultValues = documentDefaultValues.getRootElement();
			
			String defaultValue_Node_AS="", defaultValue_Node_latitude="", defaultValue_Node_longitude="";
			String defaultValue_Link_srcAS="", defaultValue_Link_tgtAS="", defaultValue_Link_length="", defaultValue_Link_bandwidth="", defaultValue_Link_delay="", defaultValue_Link_weight="", defaultValue_Link_linkType="";
			
			List listOfFormats = defaultValues.getChildren();
			Iterator ilistOfFormats = listOfFormats.iterator();
			while(ilistOfFormats.hasNext()){
				Element currentChildOfDefaultValues = (Element)ilistOfFormats.next();
				
				if(currentChildOfDefaultValues.toString().equals("[Element: <format/>]")) {
					
					if(currentChildOfDefaultValues.getAttributeValue("name").equals("RIG")){
						
						List listOfDefaultValuesOfFormat = currentChildOfDefaultValues.getChildren();
						Iterator ilistOfDefaultValuesOfFormat = listOfDefaultValuesOfFormat.iterator();
						while(ilistOfDefaultValuesOfFormat.hasNext()){
							Element currentChildOfFormat = (Element)ilistOfDefaultValuesOfFormat.next();
							
							if(currentChildOfFormat.toString().equals("[Element: <node/>]")){
								
								List listOfChildOfNode = currentChildOfFormat.getChildren();
								Iterator ilistOfChildOfNode = listOfChildOfNode.iterator();
								while(ilistOfChildOfNode.hasNext()){
									Element currentUnit = (Element)ilistOfChildOfNode.next();
									
									if(currentUnit.toString().equals("[Element: <unit/>]")){
										
										if(currentUnit.getAttributeValue("type").equals("AS")){
											defaultValue_Node_AS=currentUnit.getAttributeValue("value");
										}
										if(currentUnit.getAttributeValue("type").equals("latitude")){
											defaultValue_Node_latitude=currentUnit.getAttributeValue("value");
										}											
										if(currentUnit.getAttributeValue("type").equals("longitude")){
											defaultValue_Node_longitude=currentUnit.getAttributeValue("value");
										}											
									}
								}
							}
							
							if(currentChildOfFormat.toString().equals("[Element: <link/>]")){
								
								List listOfChildOfNode = currentChildOfFormat.getChildren();
								Iterator ilistOfChildOfNode = listOfChildOfNode.iterator();
								while(ilistOfChildOfNode.hasNext()){
									Element currentUnit = (Element)ilistOfChildOfNode.next();
									
									if(currentUnit.toString().equals("[Element: <unit/>]")){
																			
										if(currentUnit.getAttributeValue("type").equals("srcAS")){
											defaultValue_Link_srcAS=currentUnit.getAttributeValue("value");
										}
										if(currentUnit.getAttributeValue("type").equals("tgtAS")){
											defaultValue_Link_tgtAS=currentUnit.getAttributeValue("value");
										}
										if(currentUnit.getAttributeValue("type").equals("length")){
											defaultValue_Link_length=currentUnit.getAttributeValue("value");
										}											
										if(currentUnit.getAttributeValue("type").equals("bandwidth")){
											defaultValue_Link_bandwidth=currentUnit.getAttributeValue("value");
										}
										if(currentUnit.getAttributeValue("type").equals("delay")){
											defaultValue_Link_delay=currentUnit.getAttributeValue("value");
										}
										if(currentUnit.getAttributeValue("type").equals("weight")){
											defaultValue_Link_weight=currentUnit.getAttributeValue("value");
										}
										if(currentUnit.getAttributeValue("type").equals("linkType")){
											defaultValue_Link_linkType=currentUnit.getAttributeValue("value");
										}		
									}
								}
							}
						}
					}
				}
			}				
			/*************************************************************************************************************************************************/
			
            org.jdom.input.SAXBuilder builder = new org.jdom.input.SAXBuilder();
            builder.setIgnoringElementContentWhitespace(true);
            org.jdom.Document document = builder.build(ftp);
			
            domain = document.getRootElement();
			
            /* Test to know domain's sons */
            boolean BoolTopology = false;
			
            List domainChildren = domain.getChildren();
            Iterator idomainChildren = domainChildren.iterator();
            while(idomainChildren.hasNext()) {
                Element currentChild = (Element)idomainChildren.next();
                if(currentChild.toString().equals("[Element: <topology/>]")) { BoolTopology=true; }
            }
			
            if(BoolTopology==true){
                topology = domain.getChild("topology");
                nodes = topology.getChild("nodes");
                links = topology.getChild("links");
				
                int NbNodes = nodes.getChildren().size();
                int NbLinks = links.getChildren().size();
				
                /* Calculation for the date */
                Date today = new Date();
                String day = "";
                String month = "";
                if(today.getDate()<10) { day = "0"+today.getDate();} else { day = today.getDate()+""; }
                if((today.getMonth()+1)<10){ month = "0"+(today.getMonth()+1);} else { month = (today.getMonth()+1)+"";}
				
                bw.write("# generated by ParserToBrite from this jApplet");
                bw.newLine();
                bw.write("# on "+(today.getYear()+1900)+"-"+month+"-"+day);
                bw.newLine();
                bw.write("#");
                bw.newLine();
                bw.write("# Header: <num-vertices> <num-edges>");
                bw.newLine();
                bw.write(NbNodes+"\t"+NbLinks);
                bw.newLine();
				
                /* Nodes */
                bw.write("# Vertices: <node-id> <latitude> <longitude> <AS-number> [<name>]");
                bw.newLine();
				
                String AS="", idNode="", nameNode="";
                Double latitude=0.0, longitude=0.0;
				
                List listOfNode = nodes.getChildren();
                Iterator ilistOfNode = listOfNode.iterator();
                while(ilistOfNode.hasNext()){
                    Element currentNode = (Element)ilistOfNode.next();
					
                    List listOfChildOfNode = currentNode.getChildren();
                    Iterator ilistOfChildOfNode = listOfChildOfNode.iterator();
                    while(ilistOfChildOfNode.hasNext()){
                        Element currentChildNode = (Element)ilistOfChildOfNode.next();
						
                        if(currentChildNode.toString().equals("[Element: <AS/>]")){
                            AS=currentChildNode.getValue();
                        }
						
                        if(currentChildNode.toString().equals("[Element: <location/>]")){
                            List listOfAttributesOfLocation = currentChildNode.getAttributes();
                            Iterator ilistOfAttributesOfLocation = listOfAttributesOfLocation.iterator();
                            while(ilistOfAttributesOfLocation.hasNext()){
                                Attribute currentAttributeLocation = (Attribute)ilistOfAttributesOfLocation.next();
								
                                if(currentAttributeLocation.getName().equals("latitude")){
                                    latitude=Double.parseDouble(currentAttributeLocation.getValue());
                                }
								
                                if(currentAttributeLocation.getName().equals("longitude")){
                                    longitude=Double.parseDouble(currentAttributeLocation.getValue());
                                }
								
                                /* case if there is location with x & y and no latitude & longitude coordonates */
                                if(currentAttributeLocation.getName().equals("x")){
                                    if(latitude==0.0){
                                        latitude=Double.parseDouble(currentAttributeLocation.getValue());
                                    }
                                }
								
                                if(currentAttributeLocation.getName().equals("y")){
                                    if(longitude==0.0){
                                        longitude=Double.parseDouble(currentAttributeLocation.getValue());
                                    }
                                }
                            }
                        }
						
                        if(currentChildNode.toString().equals("[Element: <description/>]")){
                            List listOfAttributesOfDescription = currentChildNode.getAttributes();
                            Iterator ilistOfAttributesOfDescription = listOfAttributesOfDescription.iterator();
                            while(ilistOfAttributesOfDescription.hasNext()){
                                Attribute currentAttributeDescription = (Attribute)ilistOfAttributesOfDescription.next();
								
                                if(currentAttributeDescription.getName().equals("label")){
                                    nameNode = currentAttributeDescription.getValue();
                                }
                            }
                        }
						
                    }
					
                    /* Assignement of default values*/
                    if(AS.equals("")){
                        AS=defaultValue_Node_AS;
                    }
                    if(latitude==0.0){
                        latitude=Double.parseDouble(defaultValue_Node_latitude);
                    }
                    if(longitude==0.0){
                        longitude=Double.parseDouble(defaultValue_Node_longitude);
                    }
					
                    idNode = currentNode.getAttributeValue("id");
					
                    if(nameNode.equals("")){
                        bw.write(idNode+"\t"+latitude+"\t"+longitude+"\t"+AS);
                    }
                    else {
                        bw.write(idNode+"\t"+latitude+"\t"+longitude+"\t"+AS+"\t"+nameNode);
                    }
                    bw.newLine();
                }
				
				
				/* Links */
				bw.write("# Edges: <node-id> <node-id> <type> <bandwidth> <weight> <delay> <length>");
				bw.newLine();
				
                String srcNode="", srcAS="", tgtNode="", tgtAS="", bandwidth="", delay="", linkType="", length="", weight="";
				
				
                List listOfLink = links.getChildren();
                Iterator ilistOfLink = listOfLink.iterator();
                while(ilistOfLink.hasNext()){
                    Element currentLink = (Element)ilistOfLink.next();
					
                    List listOfChildOfLink = currentLink.getChildren();
                    Iterator ilistOfChildOfLink = listOfChildOfLink.iterator();
                    while(ilistOfChildOfLink.hasNext()){
                        Element currentChildLink = (Element)ilistOfChildOfLink.next();
						
                        if(currentChildLink.toString().equals("[Element: <source/>]")){
                            List listOfAttributeSource = currentChildLink.getAttributes();
                            Iterator ilistOfAttributeSource = listOfAttributeSource.iterator();
                            while(ilistOfAttributeSource.hasNext()){
                                Attribute currentAttributeSource = (Attribute)ilistOfAttributeSource.next();
								
                                if(currentAttributeSource.getName().equals("node")){
                                    srcNode = currentAttributeSource.getValue();
                                }
								
                                if(currentAttributeSource.getName().equals("AS")){
                                    srcAS = currentAttributeSource.getValue();
                                }
                            }
                        }
						
                        if(currentChildLink.toString().equals("[Element: <target/>]")){
                            List listOfAttributeTarget = currentChildLink.getAttributes();
                            Iterator ilistOfAttributeTarget = listOfAttributeTarget.iterator();
                            while(ilistOfAttributeTarget.hasNext()){
                                Attribute currentAttributeTarget = (Attribute)ilistOfAttributeTarget.next();
								
                                if(currentAttributeTarget.getName().equals("node")){
                                    tgtNode = currentAttributeTarget.getValue();
                                }
								
                                if(currentAttributeTarget.getName().equals("AS")){
                                    tgtAS = currentAttributeTarget.getValue();
                                }
                            }
                        }
						
                        if(currentChildLink.toString().equals("[Element: <bandwidth/>]")){
                            bandwidth = currentChildLink.getValue();
                        }
						
                        if(currentChildLink.toString().equals("[Element: <delay/>]")){
                            delay = currentChildLink.getValue();
                        }
						
                        if(currentChildLink.toString().equals("[Element: <weight/>]")){
                            weight = currentChildLink.getValue();
                        }
						
                        if(currentChildLink.toString().equals("[Element: <linkType/>]")){
                            List listOfAttributesOfType = currentChildLink.getAttributes();
                            Iterator ilistOfAttributesOfType = listOfAttributesOfType.iterator();
                            while(ilistOfAttributesOfType.hasNext()){
                                Attribute currentAttributeType = (Attribute)ilistOfAttributesOfType.next();
								
                                if(currentAttributeType.getName().equals("type2")){
                                    linkType = currentAttributeType.getValue();
                                }
                            }
                        }
						
                        if(currentChildLink.toString().equals("[Element: <length/>]")){
                            length = currentChildLink.getValue();
                        }
						
                    }
					
                    /* Assignement of default values*/
                    if(srcAS.equals("")){
                        srcAS=defaultValue_Link_srcAS;
                    }
                    if(tgtAS.equals("")){
                        tgtAS=defaultValue_Link_tgtAS;
                    }
                    if(bandwidth.equals("")){
                        bandwidth=defaultValue_Link_bandwidth;
                    }
                    if(delay.equals("")){
                        delay=defaultValue_Link_delay;
                    }
                    if(linkType.equals("")){
                        linkType=defaultValue_Link_linkType;
                    }
                    if(length.equals("")){
                        length=defaultValue_Link_length;
                    }
                    if(weight.equals("")){
                        weight=defaultValue_Link_weight;
                    }
					
                    bw.write(srcAS+":"+srcNode+"\t"+tgtAS+":"+tgtNode+"\t"+linkType+"\t"+bandwidth+"\t"+weight+"\t"+delay+"\t"+length);
                    bw.newLine();
                }
				
            }
            bw.close();
            fw.close();
			result.add("ParserToRIG","Export succeeded");
			
		} catch (Exception e) {
			e.printStackTrace();
			result.add("ParserToRIG","Export had problems "+e);
		}
    }
}
